<template>
  <view class="audio-container">
    <!-- 长方形可视化区域 -->
    <view class="bar-visualizer-container">
      <view 
        v-for="(bar, index) in visualizerBars" 
        :key="index" 
        class="visualizer-bar" 
        :style="{ 
          width: barWidth + 'px',
          height: bar.height + 'px',
          backgroundColor: bar.color,
          marginLeft: index > 0 ? barMargin + 'px' : '0',
          bottom: '0px'
        }"
      ></view>
    </view>
    
    <view class="progress-container">
      <view class="progress-bar" :style="{ width: progressPercent + '%' }"></view>
    </view>
    
    <view class="controls">
      <button @click="togglePlay">
        {{ isPlaying ? '暂停' : '播放' }}
      </button>
      <text>{{ currentTime }} / {{ duration }}</text>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'

// 基础状态
const isPlaying = ref(false)
const currentTime = ref('00:00')
const duration = ref('00:00')
const progressPercent = ref(0)

// 可视化配置（速度调整）
const barCount = ref(24)
const barWidth = ref(8)
const barMargin = ref(4)
const visualizerBars = ref([])
const smoothFactor = ref(0.4) // 增大平滑因子，让动画响应更快
const lastHeights = ref([])
const pauseTransitionFrame = ref(null) // 暂停状态的过渡动画帧

// 音频相关
const audioContext = ref(null)
const analyser = ref(null)
const dataArray = ref(null)
const animationId = ref(null)
const audioRef = ref(null)
const sourceNode = ref(null)
const barColors = ref([
  'rgba(64, 158, 255, 0.9)',
  'rgba(103, 194, 58, 0.9)',
  'rgba(230, 162, 60, 0.9)',
  'rgba(245, 108, 108, 0.9)',
  'rgba(156, 89, 218, 0.9)'
])

// 格式化时间
const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

// 切换播放状态
const togglePlay = () => {
  if (!audioRef.value) return
  
  if (isPlaying.value) {
    audioRef.value.pause()
    audioContext.value?.suspend()
    startPauseTransition() // 开始暂停过渡动画
  } else {
    audioRef.value.play()
    audioContext.value?.resume()
    stopPauseTransition() // 停止暂停过渡，恢复正常动画
  }
  isPlaying.value = !isPlaying.value
}

// 初始化音频
const initAudio = () => {
  try {
    audioRef.value = uni.createInnerAudioContext()
    audioRef.value.src = '/static/林俊杰  - 不潮不用花钱.mp3'
    audioRef.value.autoplay = false
    audioRef.value.obeyMuteSwitch = false
    
    // 音频事件监听
    audioRef.value.onPlay(() => {
      isPlaying.value = true
      if (!audioContext.value) {
        initAudioContext()
      } else {
        stopPauseTransition() // 从暂停状态恢复播放
      }
    })
    
    audioRef.value.onPause(() => {
      isPlaying.value = false
      startPauseTransition() // 进入暂停过渡
    })
    
    audioRef.value.onEnded(() => {
      isPlaying.value = false
      audioRef.value.seek(0)
      resetVisualizer()
      startPauseTransition() // 播放结束也执行暂停过渡
    })
    
    audioRef.value.onTimeUpdate(() => {
      if (audioRef.value.duration) {
        currentTime.value = formatTime(audioRef.value.currentTime)
        duration.value = formatTime(audioRef.value.duration)
        progressPercent.value = (audioRef.value.currentTime / audioRef.value.duration) * 100
      }
    })
    
  } catch (error) {
    console.error('音频初始化失败:', error)
    uni.showToast({ title: '音频加载失败', icon: 'none' })
  }
}

// 重置可视化
const resetVisualizer = () => {
  visualizerBars.value = Array.from({ length: barCount.value }, (_, i) => ({
    height: 10,
    color: barColors.value[i % barColors.value.length]
  }))
  lastHeights.value = visualizerBars.value.map(bar => bar.height)
}

// 初始化音频上下文
const initAudioContext = () => {
  try {
    audioContext.value = new (window.AudioContext || window.webkitAudioContext)()
    analyser.value = audioContext.value.createAnalyser()
    analyser.value.smoothingTimeConstant = 0.75 // 减小平滑时间，让变化更快响应
    
    // 加载音频文件并连接到分析器
    fetch(audioRef.value.src)
      .then(response => response.arrayBuffer())
      .then(arrayBuffer => audioContext.value.decodeAudioData(arrayBuffer))
      .then(audioBuffer => {
        const source = audioContext.value.createBufferSource()
        source.buffer = audioBuffer
        source.connect(analyser.value)
        analyser.value.connect(audioContext.value.destination)
        sourceNode.value = source
        
        // 同步播放进度
        source.start(0, audioRef.value.currentTime)
        
        // 配置分析器
        analyser.value.fftSize = 256
        const bufferLength = analyser.value.frequencyBinCount
        dataArray.value = new Uint8Array(bufferLength)
        
        // 开始动画
        resetVisualizer()
        animate()
      })
      .catch(error => {
        console.error('音频解码失败:', error)
        uni.showToast({ title: '可视化初始化失败', icon: 'none' })
      })
    
  } catch (error) {
    console.error('音频上下文初始化失败:', error)
    uni.showToast({ title: '可视化加载失败', icon: 'none' })
  }
}

// 暂停状态的过渡动画 - 高度逐渐降为0
const startPauseTransition = () => {
  // 先停止正常动画
  if (animationId.value) {
    cancelAnimationFrame(animationId.value)
    animationId.value = null
  }
  
  // 保存当前高度状态
  lastHeights.value = visualizerBars.value.map(bar => bar.height)
  
  // 开始暂停过渡动画
  const transition = () => {
    visualizerBars.value = visualizerBars.value.map((bar, index) => {
      // 每次减少当前高度的10%，实现渐进式下降
      const newHeight = Math.max(0, lastHeights.value[index] * 0.9)
      lastHeights.value[index] = newHeight
      return { ...bar, height: newHeight }
    })
    
    // 如果还有高度大于0，继续动画
    if (lastHeights.value.some(h => h > 0.5)) {
      pauseTransitionFrame.value = requestAnimationFrame(transition)
    }
  }
  
  pauseTransitionFrame.value = requestAnimationFrame(transition)
}

// 停止暂停过渡，恢复正常动画
const stopPauseTransition = () => {
  // 停止暂停过渡动画
  if (pauseTransitionFrame.value) {
    cancelAnimationFrame(pauseTransitionFrame.value)
    pauseTransitionFrame.value = null
  }
  
  // 重新开始正常动画
  if (!animationId.value && analyser.value) {
    animate()
  }
}

// 动画循环
const animate = () => {
  if (!analyser.value || !isPlaying.value) return
  
  animationId.value = requestAnimationFrame(animate)
  analyser.value.getByteFrequencyData(dataArray.value)
  
  const container = document.querySelector('.bar-visualizer-container')
  const containerHeight = container?.clientHeight || 200
  const maxBarHeight = containerHeight * 0.8
  
  visualizerBars.value = visualizerBars.value.map((bar, index) => {
    const frequency = dataArray.value[index % dataArray.value.length] / 250 // 减小分母，提高灵敏度
    
    // 计算目标高度（添加轻微随机性，使动画更生动）
    const targetHeight = 10 + (frequency * maxBarHeight * (0.95 + Math.random() * 0.1))
    
    // 平滑过渡（更快响应）
    const currentHeight = lastHeights.value[index] + (targetHeight - lastHeights.value[index]) * smoothFactor.value
    lastHeights.value[index] = currentHeight
    
    return { ...bar, height: currentHeight }
  })
}

onMounted(() => {
  nextTick(() => {
    const container = document.querySelector('.bar-visualizer-container')
    if (container) {
      const containerWidth = container.clientWidth
      const totalBarWidth = barCount.value * barWidth.value + (barCount.value - 1) * barMargin.value
      if (totalBarWidth > containerWidth) {
        const availableWidth = containerWidth - (barCount.value - 1) * barMargin.value
        barWidth.value = Math.max(2, Math.floor(availableWidth / barCount.value))
      }
    }
    initAudio()
  })
})

onUnmounted(() => {
  // 清理所有动画帧
  if (animationId.value) cancelAnimationFrame(animationId.value)
  if (pauseTransitionFrame.value) cancelAnimationFrame(pauseTransitionFrame.value)
  
  // 清理音频资源
  if (sourceNode.value) sourceNode.value.stop()
  if (audioRef.value) {
    audioRef.value.stop()
    audioRef.value.destroy()
  }
  if (audioContext.value) audioContext.value.close()
})
</script>

<style scoped>
/* 样式保持不变 */
.audio-container {
  width: 100%;
  padding: 20px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.bar-visualizer-container {
  width: 100%;
  height: 200px;
  background-color: #f5f5f5;
  position: relative;
  margin-bottom: 20px;
  padding: 0 10px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

.visualizer-bar {
  position: relative;
  border-radius: 4px 4px 0 0;
  transition: height 0.05s ease-out; 
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.progress-container {
  width: 100%;
  height: 4px;
  background-color: #e4e7ed;
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 15px;
}

.progress-bar {
  height: 100%;
  background-color: #409eff;
  transition: width 0.1s linear;
}

.controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

button {
  padding: 8px 15px;
  background-color: #409eff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #66b1ff;
}

text {
  font-size: 14px;
  color: #606266;
}
</style>